package com.xxxx.yebserver.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxxx.yebserver.constant.RedisContant;
import com.xxxx.yebserver.entity.Admin;
import com.xxxx.yebserver.entity.Menu;
import com.xxxx.yebserver.entity.MenuRole;
import com.xxxx.yebserver.mapper.MenuMapper;
import com.xxxx.yebserver.pojo.MySecurityUser;
import com.xxxx.yebserver.service.MenuRoleService;
import com.xxxx.yebserver.service.MenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxx.yebserver.service.RoleService;
import com.xxxx.yebserver.vo.MenusWithRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cxq
 * @since 2021-06-15
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    RoleService roleService;

    @Autowired
    MenuRoleService menuRoleService;

    /**
     * 根据id获取对应的菜单
     * @return
     */
    @Override
    public List<Menu> getMenusByAdminId() {
        MySecurityUser user = (MySecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Admin admin = user.getAdmin();
        String s = redisTemplate.opsForValue().get(RedisContant.MENU_ADMIN_PREFIX + admin.getUsername());
        List<Menu> list = null;
        if(StringUtils.isEmpty(s)){
            List<Menu> menus = baseMapper.getMenusByAdminId(admin.getAdminId());
            if(menus == null || menus.size() == 0) throw new RuntimeException("菜单列表为空，请先设置！");
            list = getMenuChildren(menus,1L);
            redisTemplate.opsForValue().set(RedisContant.MENU_ADMIN_PREFIX + admin.getUsername(), JSON.toJSONString(list));
        }else{
            list = JSON.parseObject(s,new TypeReference<List<Menu>>(){});
        }
        return list;
    }

    /**
     * 根据角色获取对应的菜单
     * @return
     */
    @Cacheable(value = "menu",key = "#root.methodName")
    @Override
    public List<MenusWithRoleVo> getMenusWithRole() {
        return baseMapper.getMenusWithRole();
    }

    @Cacheable(value = "menu",key = "#root.methodName")
    @Override
    public List<Menu> getAllTreeMenus() {
        List<Menu> list = list();
        if(list != null && list.size() > 0){
            return getMenuChildren(list,1L);
        }
        return null;
    }

    private  List<Menu> getMenuChildren(List<Menu> menus, Long pid){
       return menus.stream().filter(menu -> menu.getParentId() == pid)
                .map(menu -> {
                    menu.setChildren(getMenuChildren(menus,menu.getMenuId()));
                    return menu;
                }).collect(Collectors.toList());
    }



    /**
     * 跟新角色ID对应的菜单信息
     * @param rid
     * @param mids
     * @return
     */
    @Override
    public Boolean updateMenuRoles(Long rid, Long[] mids) {
        if(mids == null || mids.length == 0) return true;
        boolean delete = menuRoleService.remove(new QueryWrapper<MenuRole>().eq("role_id", rid));
        if(!delete) return false;
        ArrayList<MenuRole> menuRoles = new ArrayList<>();
        for(Long mid : mids){
            MenuRole mr = new MenuRole();
            mr.setRoleId(rid);
            mr.setMenuId(mid);
            menuRoles.add(mr);
        }
        return menuRoleService.saveBatch(menuRoles);
    }
}
